package org.gthelper.handler;

import java.awt.image.RenderedImage;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.UUID;

import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.geometry.GeneralEnvelope;
import org.geotools.referencing.CRS;
import org.gthelper.data.DataGeter;
import org.gthelper.data.SendData;
import org.gthelper.database.FileInfo;
import org.gthelper.database.FileStatus;
import org.gthelper.error.ErrorCode;
import org.gthelper.hdfs.HdfsMA;
import org.gthelper.hdpWritable.HdpRenderedImageWritable;
import org.gthelper.imageProcess.geotiffTreater;
import org.gthelper.order.OrderInfo;
import org.gthelper.server.SysInfo;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;

/**
 * 下载文件
 * @author pig
 *
 */
public class Download extends Handler
{

	@SuppressWarnings("finally")
	@Override
	public int handle(OrderInfo orderinfo) {
		// TODO 自动生成的方法存根
		//get id
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		DataGeter dg = new DataGeter();
		int errcode=dg.getData(orderinfo.orderStream, baos);
		if(errcode!=ErrorCode.NORMAL)return errcode;
		byte[] userid = baos.toByteArray();
		baos.reset();
		
		//get filename
		errcode = dg.getData(orderinfo.orderStream, baos);
		if(errcode!=ErrorCode.NORMAL)return errcode;
		byte[] filename = baos.toByteArray();
		baos.reset();
		
		//to String
		String usrid="";
		String fileName="";
		try {
			usrid = new String(userid,"UTF-8");
			fileName = new String(filename,"UTF-8");
		} catch (UnsupportedEncodingException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
			return ErrorCode.UNKNOWN;
		}
		if((fileName.indexOf('/'))>-1)return ErrorCode.WRONGNAME;
		if((fileName.indexOf('\\'))>-1)return ErrorCode.WRONGNAME;
		
		//check
		FileInfo fileinfo=null;
		try {
			fileinfo=FileInfo.getfileInfobyuserIDandfilename(usrid, fileName);
		} catch (Exception e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
			return ErrorCode.DATABASEERR;
		}
		if(fileinfo.getstatus()<0)return ErrorCode.FILENOTEXIST;
		else if(fileinfo.getstatus()==FileStatus.deleting)return ErrorCode.DELETING;
		
		fileinfo.setstatus(FileStatus.downloading);
		fileinfo.updatefilelist();
		
		//get splited filename
		String fpath = "/"+usrid+"/"+fileName+"/"+fileName;
		ArrayList<String> splitCode = fileinfo.getSplitCode();
		
		//create geotiff temp file
		String tmppath = SysInfo.downTempPath+"/"+usrid;
		String tmpname = "/"+UUID.randomUUID()+"tif";
		File tmpfile = new File(tmppath+tmpname);
		File tmppathfile = new File(tmppath);
		if((!tmppathfile.exists())&&(!tmppathfile.isDirectory()))
		{
			tmppathfile.mkdirs();
		}
		while(true)
		{
			if(tmpfile.exists())
			{
				tmpname="/"+UUID.randomUUID()+"tif";
				tmpfile = new File(tmppath+tmpname);
			}
			else
			{
				try {
					tmpfile.createNewFile();
				} catch (IOException e) {
					// TODO 自动生成\00\00 catch \00\00
					e.printStackTrace();
					fileinfo.setstatus(FileStatus.uploaderr);
					fileinfo.updatefilelist();
					return ErrorCode.IOEXC;
				}
				break;
			}
		}
		
		//get data from hdfs
		ArrayList<HdpRenderedImageWritable> hriwList = new ArrayList<HdpRenderedImageWritable>();
		int count = splitCode.size();
		HdfsMA ma = new HdfsMA();
		for(int n=0;n<count;n++)
		{
			try {
				hriwList.add(ma.readSingleSeqFile(fpath+splitCode.get(n)+".seq"));
			} catch (IOException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
				fileinfo.setstatus(FileStatus.normal);
				fileinfo.updatefilelist();
				return ErrorCode.FROMHDFS;
			}
		}
		
		//write geotiff to temp file
		geotiffTreater gtt = new geotiffTreater();
		RenderedImage ri = gtt.imagejoint(hriwList, fileinfo.getpixelsize_x(), fileinfo.getpixelsize_y());
		CoordinateReferenceSystem crs;
		try {
			crs = CRS.parseWKT(fileinfo.getCRS_decode());
		} catch (FactoryException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
			fileinfo.setstatus(FileStatus.normal);
			fileinfo.updatefilelist();
			return ErrorCode.UNKNOWN;
		}
		GeneralEnvelope env = new GeneralEnvelope(crs);
	    env.setRange(0, 0, 360);
	    env.setRange(1, -90, 90);
		//还要干什么？
		GridCoverage2D gc = gtt.creategeotifffromrenderimage(fileinfo.getfilename(),ri, env);
		try {
			gtt.saveGeotiff(gc, tmppath+tmpname, null);
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
			fileinfo.setstatus(FileStatus.normal);
			fileinfo.updatefilelist();
			tmpfile.delete();
			return ErrorCode.IOEXC;
		}
		
		//return geotiff
		DataOutputStream dos = new DataOutputStream(orderinfo.mainOutput);
		File resultfile = new File(tmppath+tmpname);
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(resultfile);
		} catch (FileNotFoundException e1) {
			// TODO 自动生成的 catch 块
			e1.printStackTrace();
			
		}
		try {
			dos.writeLong(resultfile.length());
			SendData.send(fis, dos,819200);
			dos.flush();
			dos.close();
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}finally
		{
			//reset file status
			fileinfo.setstatus(FileStatus.normal);
			fileinfo.updatefilelist();
			tmpfile.delete();
			return ErrorCode.NORMAL;
		}
	}
	
}